package com.sokcet.io;

import com.controller.abstractcontroller.IController;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.kit.NamedThreadFactory;
import com.vo.PlayerInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by 石头哥哥 on 8/20/16.
 * PACKAGE_NAME:  com.sokcet.io
 * COMMENT :
 */
@Component
public class ServerSocketIoHandler {

    /**
     * logger
     */
    private final Logger logger = LoggerFactory.getLogger(ServerSocketIoHandler.class);

    /**
     *
     */
    private SocketIOServer socketIOServer;
    /**
     * socketid处理的事件类型
     */
    final private String EVENT_NAME = "msg";
    /**
     * 用于执行逻辑处理
     */
    final private ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new NamedThreadFactory("游戏逻辑处理线程池"));


    /**
     * channel is active
     */
    private boolean active = false;//channel is active  ?


    /**
     * 游戏逻辑session
     */
    private PlayerInstance player;


    /**
     * @param socketIOServer
     */
    protected ServerSocketIoHandler(SocketIOServer socketIOServer) {
        this.socketIOServer = socketIOServer;
    }


    /**
     * 启动网络
     */
    protected void start() {
        addListener();
        this.socketIOServer.start();
    }


    /**
     * 注册 连接 ,连接断开事件监听器
     */
    private void addListener() {
        socketIOServer.addConnectListener(new ConnectListener() {
            @Override
            public void onConnect(SocketIOClient client) {
                logger.info("new client connect server:" + client.toString()
                        + "\nuuid:" + client.getSessionId());
                active = true;
                player = new PlayerInstance(client, client.getSessionId(),EVENT_NAME);
            }
        });

        socketIOServer.addDisconnectListener(new DisconnectListener() {
            @Override
            public void onDisconnect(SocketIOClient client) {
                logger.info(client.getRemoteAddress().toString() + " disconnect!");
            }
        });

        //处理数据分发
        onReadData();
    }


    /**
     * 处理数据分发
     */
    private void onReadData() {
        socketIOServer.addEventListener(EVENT_NAME, byte[].class, new DataListener<byte[]>() {
            @Override
            public void onData(SocketIOClient client, final byte[] data, AckRequest ackSender) throws Exception {
                //当前线程为io线程
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        dispatchMessage(data, player);
                        logger.info("接收到客户端数据:" + new String(data));
                    }
                });
            }
        });
    }


    /**
     * 逻辑线程处理消息数据
     *
     * @param data
     */
    @SuppressWarnings("Duplicates")
    private void dispatchMessage(final byte[] data, final PlayerInstance player) {
        try {
            if (active) {
                //获取 消息标识ID
                int ID = (data[0x0] & 0xff) << 0x18 |
                        (data[0x1] & 0xff) << 0x10 |
                        (data[0x2] & 0xff) << 0x8 | data[0x3] & 0xff;

                int length = data.length - 0x4;//数据包长度

                // for flat buffer
                if (length != 0) {
                    IController.game_controllers[ID].DispatchFlatBuffer(data, player);
                } else {      //only id
                    IController.game_controllers[ID].DispatchFlatBuffer(null, player);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
